# Copyright 2022 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2

# whirlpool.py - pure Python implementation of the Whirlpool algorithm.
# Bjorn Edstrom <be@bjrn.se> 16 december 2007.
##
# Copyrights
# ==========
##
# This code is based on the reference implementation by
# Paulo S.L.M. Barreto and Vincent Rijmen. The reference implementation
# is placed in the public domain but has the following headers:
##
# * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
# * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
# * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
# * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
# * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# *
# */
# /* The code contained in this file (Whirlpool.c) is in the public domain. */
##
# This Python implementation is therefore also placed in the public domain.

# pylint: disable=mixed-indentation

import warnings

from portage.localization import _

try:
    from ._whirlpool import Whirlpool as WhirlpoolExt
except ImportError:
    WhirlpoolExt = None


# block_size = 64
digest_size = 64
digestsize = 64


class PyWhirlpool:
    """Return a new Whirlpool object. An optional string argument
    may be provided; if present, this string will be automatically
    hashed."""

    def __init__(self, arg=b""):
        warnings.warn(
            _(
                "The last-resort unaccelerated Whirlpool implementation is "
                "being used. It is known to be absurdly slow. Please report "
                "that the Whirlpool hash is deprecated to the repository owner."
            )
        )
        self.ctx = WhirlpoolStruct()
        self.update(arg)

    def update(self, arg):
        """update(arg)"""
        WhirlpoolAdd(arg, len(arg) * 8, self.ctx)
        self.digest_status = 0

    def digest(self):
        """digest()"""
        if self.digest_status == 0:
            self.dig = WhirlpoolFinalize(self.ctx)
        self.digest_status = 1
        return self.dig

    def hexdigest(self):
        """hexdigest()"""
        dig = self.digest()
        tempstr = ""
        for d in dig:
            xxx = f"{ord(d):02x}"
            tempstr = tempstr + xxx
        return tempstr

    def copy(self):
        """copy()"""
        import copy

        return copy.deepcopy(self)


class CWhirlpool:
    """Return a new Whirlpool object. An optional string argument
    may be provided; if present, this string will be automatically
    hashed."""

    is_available = WhirlpoolExt is not None

    def __init__(self, arg=b""):
        self.obj = WhirlpoolExt()
        self.dig = None
        self.update(arg)

    def update(self, arg):
        if self.dig is not None:
            raise RuntimeError("Whirlpool object already finalized")
        self.obj.update(arg)

    def digest(self):
        if self.dig is None:
            self.dig = self.obj.digest()
        return self.dig

    def hexdigest(self):
        """hexdigest()"""
        dig = self.digest()
        tempstr = ""
        for d in dig:
            xxx = f"{d:02x}"
            tempstr = tempstr + xxx
        return tempstr


#
# Private.
#


R = 10

C0 = [
    0x18186018C07830D8,
    0x23238C2305AF4626,
    0xC6C63FC67EF991B8,
    0xE8E887E8136FCDFB,
    0x878726874CA113CB,
    0xB8B8DAB8A9626D11,
    0x0101040108050209,
    0x4F4F214F426E9E0D,
    0x3636D836ADEE6C9B,
    0xA6A6A2A6590451FF,
    0xD2D26FD2DEBDB90C,
    0xF5F5F3F5FB06F70E,
    0x7979F979EF80F296,
    0x6F6FA16F5FCEDE30,
    0x91917E91FCEF3F6D,
    0x52525552AA07A4F8,
    0x60609D6027FDC047,
    0xBCBCCABC89766535,
    0x9B9B569BACCD2B37,
    0x8E8E028E048C018A,
    0xA3A3B6A371155BD2,
    0x0C0C300C603C186C,
    0x7B7BF17BFF8AF684,
    0x3535D435B5E16A80,
    0x1D1D741DE8693AF5,
    0xE0E0A7E05347DDB3,
    0xD7D77BD7F6ACB321,
    0xC2C22FC25EED999C,
    0x2E2EB82E6D965C43,
    0x4B4B314B627A9629,
    0xFEFEDFFEA321E15D,
    0x575741578216AED5,
    0x15155415A8412ABD,
    0x7777C1779FB6EEE8,
    0x3737DC37A5EB6E92,
    0xE5E5B3E57B56D79E,
    0x9F9F469F8CD92313,
    0xF0F0E7F0D317FD23,
    0x4A4A354A6A7F9420,
    0xDADA4FDA9E95A944,
    0x58587D58FA25B0A2,
    0xC9C903C906CA8FCF,
    0x2929A429558D527C,
    0x0A0A280A5022145A,
    0xB1B1FEB1E14F7F50,
    0xA0A0BAA0691A5DC9,
    0x6B6BB16B7FDAD614,
    0x85852E855CAB17D9,
    0xBDBDCEBD8173673C,
    0x5D5D695DD234BA8F,
    0x1010401080502090,
    0xF4F4F7F4F303F507,
    0xCBCB0BCB16C08BDD,
    0x3E3EF83EEDC67CD3,
    0x0505140528110A2D,
    0x676781671FE6CE78,
    0xE4E4B7E47353D597,
    0x27279C2725BB4E02,
    0x4141194132588273,
    0x8B8B168B2C9D0BA7,
    0xA7A7A6A7510153F6,
    0x7D7DE97DCF94FAB2,
    0x95956E95DCFB3749,
    0xD8D847D88E9FAD56,
    0xFBFBCBFB8B30EB70,
    0xEEEE9FEE2371C1CD,
    0x7C7CED7CC791F8BB,
    0x6666856617E3CC71,
    0xDDDD53DDA68EA77B,
    0x17175C17B84B2EAF,
    0x4747014702468E45,
    0x9E9E429E84DC211A,
    0xCACA0FCA1EC589D4,
    0x2D2DB42D75995A58,
    0xBFBFC6BF9179632E,
    0x07071C07381B0E3F,
    0xADAD8EAD012347AC,
    0x5A5A755AEA2FB4B0,
    0x838336836CB51BEF,
    0x3333CC3385FF66B6,
    0x636391633FF2C65C,
    0x02020802100A0412,
    0xAAAA92AA39384993,
    0x7171D971AFA8E2DE,
    0xC8C807C80ECF8DC6,
    0x19196419C87D32D1,
    0x494939497270923B,
    0xD9D943D9869AAF5F,
    0xF2F2EFF2C31DF931,
    0xE3E3ABE34B48DBA8,
    0x5B5B715BE22AB6B9,
    0x88881A8834920DBC,
    0x9A9A529AA4C8293E,
    0x262698262DBE4C0B,
    0x3232C8328DFA64BF,
    0xB0B0FAB0E94A7D59,
    0xE9E983E91B6ACFF2,
    0x0F0F3C0F78331E77,
    0xD5D573D5E6A6B733,
    0x80803A8074BA1DF4,
    0xBEBEC2BE997C6127,
    0xCDCD13CD26DE87EB,
    0x3434D034BDE46889,
    0x48483D487A759032,
    0xFFFFDBFFAB24E354,
    0x7A7AF57AF78FF48D,
    0x90907A90F4EA3D64,
    0x5F5F615FC23EBE9D,
    0x202080201DA0403D,
    0x6868BD6867D5D00F,
    0x1A1A681AD07234CA,
    0xAEAE82AE192C41B7,
    0xB4B4EAB4C95E757D,
    0x54544D549A19A8CE,
    0x93937693ECE53B7F,
    0x222288220DAA442F,
    0x64648D6407E9C863,
    0xF1F1E3F1DB12FF2A,
    0x7373D173BFA2E6CC,
    0x12124812905A2482,
    0x40401D403A5D807A,
    0x0808200840281048,
    0xC3C32BC356E89B95,
    0xECEC97EC337BC5DF,
    0xDBDB4BDB9690AB4D,
    0xA1A1BEA1611F5FC0,
    0x8D8D0E8D1C830791,
    0x3D3DF43DF5C97AC8,
    0x97976697CCF1335B,
    0x0000000000000000,
    0xCFCF1BCF36D483F9,
    0x2B2BAC2B4587566E,
    0x7676C57697B3ECE1,
    0x8282328264B019E6,
    0xD6D67FD6FEA9B128,
    0x1B1B6C1BD87736C3,
    0xB5B5EEB5C15B7774,
    0xAFAF86AF112943BE,
    0x6A6AB56A77DFD41D,
    0x50505D50BA0DA0EA,
    0x45450945124C8A57,
    0xF3F3EBF3CB18FB38,
    0x3030C0309DF060AD,
    0xEFEF9BEF2B74C3C4,
    0x3F3FFC3FE5C37EDA,
    0x55554955921CAAC7,
    0xA2A2B2A2791059DB,
    0xEAEA8FEA0365C9E9,
    0x656589650FECCA6A,
    0xBABAD2BAB9686903,
    0x2F2FBC2F65935E4A,
    0xC0C027C04EE79D8E,
    0xDEDE5FDEBE81A160,
    0x1C1C701CE06C38FC,
    0xFDFDD3FDBB2EE746,
    0x4D4D294D52649A1F,
    0x92927292E4E03976,
    0x7575C9758FBCEAFA,
    0x06061806301E0C36,
    0x8A8A128A249809AE,
    0xB2B2F2B2F940794B,
    0xE6E6BFE66359D185,
    0x0E0E380E70361C7E,
    0x1F1F7C1FF8633EE7,
    0x6262956237F7C455,
    0xD4D477D4EEA3B53A,
    0xA8A89AA829324D81,
    0x96966296C4F43152,
    0xF9F9C3F99B3AEF62,
    0xC5C533C566F697A3,
    0x2525942535B14A10,
    0x59597959F220B2AB,
    0x84842A8454AE15D0,
    0x7272D572B7A7E4C5,
    0x3939E439D5DD72EC,
    0x4C4C2D4C5A619816,
    0x5E5E655ECA3BBC94,
    0x7878FD78E785F09F,
    0x3838E038DDD870E5,
    0x8C8C0A8C14860598,
    0xD1D163D1C6B2BF17,
    0xA5A5AEA5410B57E4,
    0xE2E2AFE2434DD9A1,
    0x616199612FF8C24E,
    0xB3B3F6B3F1457B42,
    0x2121842115A54234,
    0x9C9C4A9C94D62508,
    0x1E1E781EF0663CEE,
    0x4343114322528661,
    0xC7C73BC776FC93B1,
    0xFCFCD7FCB32BE54F,
    0x0404100420140824,
    0x51515951B208A2E3,
    0x99995E99BCC72F25,
    0x6D6DA96D4FC4DA22,
    0x0D0D340D68391A65,
    0xFAFACFFA8335E979,
    0xDFDF5BDFB684A369,
    0x7E7EE57ED79BFCA9,
    0x242490243DB44819,
    0x3B3BEC3BC5D776FE,
    0xABAB96AB313D4B9A,
    0xCECE1FCE3ED181F0,
    0x1111441188552299,
    0x8F8F068F0C890383,
    0x4E4E254E4A6B9C04,
    0xB7B7E6B7D1517366,
    0xEBEB8BEB0B60CBE0,
    0x3C3CF03CFDCC78C1,
    0x81813E817CBF1FFD,
    0x94946A94D4FE3540,
    0xF7F7FBF7EB0CF31C,
    0xB9B9DEB9A1676F18,
    0x13134C13985F268B,
    0x2C2CB02C7D9C5851,
    0xD3D36BD3D6B8BB05,
    0xE7E7BBE76B5CD38C,
    0x6E6EA56E57CBDC39,
    0xC4C437C46EF395AA,
    0x03030C03180F061B,
    0x565645568A13ACDC,
    0x44440D441A49885E,
    0x7F7FE17FDF9EFEA0,
    0xA9A99EA921374F88,
    0x2A2AA82A4D825467,
    0xBBBBD6BBB16D6B0A,
    0xC1C123C146E29F87,
    0x53535153A202A6F1,
    0xDCDC57DCAE8BA572,
    0x0B0B2C0B58271653,
    0x9D9D4E9D9CD32701,
    0x6C6CAD6C47C1D82B,
    0x3131C43195F562A4,
    0x7474CD7487B9E8F3,
    0xF6F6FFF6E309F115,
    0x464605460A438C4C,
    0xACAC8AAC092645A5,
    0x89891E893C970FB5,
    0x14145014A04428B4,
    0xE1E1A3E15B42DFBA,
    0x16165816B04E2CA6,
    0x3A3AE83ACDD274F7,
    0x6969B9696FD0D206,
    0x09092409482D1241,
    0x7070DD70A7ADE0D7,
    0xB6B6E2B6D954716F,
    0xD0D067D0CEB7BD1E,
    0xEDED93ED3B7EC7D6,
    0xCCCC17CC2EDB85E2,
    0x424215422A578468,
    0x98985A98B4C22D2C,
    0xA4A4AAA4490E55ED,
    0x2828A0285D885075,
    0x5C5C6D5CDA31B886,
    0xF8F8C7F8933FED6B,
    0x8686228644A411C2,
]
C1 = [
    0xD818186018C07830,
    0x2623238C2305AF46,
    0xB8C6C63FC67EF991,
    0xFBE8E887E8136FCD,
    0xCB878726874CA113,
    0x11B8B8DAB8A9626D,
    0x0901010401080502,
    0x0D4F4F214F426E9E,
    0x9B3636D836ADEE6C,
    0xFFA6A6A2A6590451,
    0x0CD2D26FD2DEBDB9,
    0x0EF5F5F3F5FB06F7,
    0x967979F979EF80F2,
    0x306F6FA16F5FCEDE,
    0x6D91917E91FCEF3F,
    0xF852525552AA07A4,
    0x4760609D6027FDC0,
    0x35BCBCCABC897665,
    0x379B9B569BACCD2B,
    0x8A8E8E028E048C01,
    0xD2A3A3B6A371155B,
    0x6C0C0C300C603C18,
    0x847B7BF17BFF8AF6,
    0x803535D435B5E16A,
    0xF51D1D741DE8693A,
    0xB3E0E0A7E05347DD,
    0x21D7D77BD7F6ACB3,
    0x9CC2C22FC25EED99,
    0x432E2EB82E6D965C,
    0x294B4B314B627A96,
    0x5DFEFEDFFEA321E1,
    0xD5575741578216AE,
    0xBD15155415A8412A,
    0xE87777C1779FB6EE,
    0x923737DC37A5EB6E,
    0x9EE5E5B3E57B56D7,
    0x139F9F469F8CD923,
    0x23F0F0E7F0D317FD,
    0x204A4A354A6A7F94,
    0x44DADA4FDA9E95A9,
    0xA258587D58FA25B0,
    0xCFC9C903C906CA8F,
    0x7C2929A429558D52,
    0x5A0A0A280A502214,
    0x50B1B1FEB1E14F7F,
    0xC9A0A0BAA0691A5D,
    0x146B6BB16B7FDAD6,
    0xD985852E855CAB17,
    0x3CBDBDCEBD817367,
    0x8F5D5D695DD234BA,
    0x9010104010805020,
    0x07F4F4F7F4F303F5,
    0xDDCBCB0BCB16C08B,
    0xD33E3EF83EEDC67C,
    0x2D0505140528110A,
    0x78676781671FE6CE,
    0x97E4E4B7E47353D5,
    0x0227279C2725BB4E,
    0x7341411941325882,
    0xA78B8B168B2C9D0B,
    0xF6A7A7A6A7510153,
    0xB27D7DE97DCF94FA,
    0x4995956E95DCFB37,
    0x56D8D847D88E9FAD,
    0x70FBFBCBFB8B30EB,
    0xCDEEEE9FEE2371C1,
    0xBB7C7CED7CC791F8,
    0x716666856617E3CC,
    0x7BDDDD53DDA68EA7,
    0xAF17175C17B84B2E,
    0x454747014702468E,
    0x1A9E9E429E84DC21,
    0xD4CACA0FCA1EC589,
    0x582D2DB42D75995A,
    0x2EBFBFC6BF917963,
    0x3F07071C07381B0E,
    0xACADAD8EAD012347,
    0xB05A5A755AEA2FB4,
    0xEF838336836CB51B,
    0xB63333CC3385FF66,
    0x5C636391633FF2C6,
    0x1202020802100A04,
    0x93AAAA92AA393849,
    0xDE7171D971AFA8E2,
    0xC6C8C807C80ECF8D,
    0xD119196419C87D32,
    0x3B49493949727092,
    0x5FD9D943D9869AAF,
    0x31F2F2EFF2C31DF9,
    0xA8E3E3ABE34B48DB,
    0xB95B5B715BE22AB6,
    0xBC88881A8834920D,
    0x3E9A9A529AA4C829,
    0x0B262698262DBE4C,
    0xBF3232C8328DFA64,
    0x59B0B0FAB0E94A7D,
    0xF2E9E983E91B6ACF,
    0x770F0F3C0F78331E,
    0x33D5D573D5E6A6B7,
    0xF480803A8074BA1D,
    0x27BEBEC2BE997C61,
    0xEBCDCD13CD26DE87,
    0x893434D034BDE468,
    0x3248483D487A7590,
    0x54FFFFDBFFAB24E3,
    0x8D7A7AF57AF78FF4,
    0x6490907A90F4EA3D,
    0x9D5F5F615FC23EBE,
    0x3D202080201DA040,
    0x0F6868BD6867D5D0,
    0xCA1A1A681AD07234,
    0xB7AEAE82AE192C41,
    0x7DB4B4EAB4C95E75,
    0xCE54544D549A19A8,
    0x7F93937693ECE53B,
    0x2F222288220DAA44,
    0x6364648D6407E9C8,
    0x2AF1F1E3F1DB12FF,
    0xCC7373D173BFA2E6,
    0x8212124812905A24,
    0x7A40401D403A5D80,
    0x4808082008402810,
    0x95C3C32BC356E89B,
    0xDFECEC97EC337BC5,
    0x4DDBDB4BDB9690AB,
    0xC0A1A1BEA1611F5F,
    0x918D8D0E8D1C8307,
    0xC83D3DF43DF5C97A,
    0x5B97976697CCF133,
    0x0000000000000000,
    0xF9CFCF1BCF36D483,
    0x6E2B2BAC2B458756,
    0xE17676C57697B3EC,
    0xE68282328264B019,
    0x28D6D67FD6FEA9B1,
    0xC31B1B6C1BD87736,
    0x74B5B5EEB5C15B77,
    0xBEAFAF86AF112943,
    0x1D6A6AB56A77DFD4,
    0xEA50505D50BA0DA0,
    0x5745450945124C8A,
    0x38F3F3EBF3CB18FB,
    0xAD3030C0309DF060,
    0xC4EFEF9BEF2B74C3,
    0xDA3F3FFC3FE5C37E,
    0xC755554955921CAA,
    0xDBA2A2B2A2791059,
    0xE9EAEA8FEA0365C9,
    0x6A656589650FECCA,
    0x03BABAD2BAB96869,
    0x4A2F2FBC2F65935E,
    0x8EC0C027C04EE79D,
    0x60DEDE5FDEBE81A1,
    0xFC1C1C701CE06C38,
    0x46FDFDD3FDBB2EE7,
    0x1F4D4D294D52649A,
    0x7692927292E4E039,
    0xFA7575C9758FBCEA,
    0x3606061806301E0C,
    0xAE8A8A128A249809,
    0x4BB2B2F2B2F94079,
    0x85E6E6BFE66359D1,
    0x7E0E0E380E70361C,
    0xE71F1F7C1FF8633E,
    0x556262956237F7C4,
    0x3AD4D477D4EEA3B5,
    0x81A8A89AA829324D,
    0x5296966296C4F431,
    0x62F9F9C3F99B3AEF,
    0xA3C5C533C566F697,
    0x102525942535B14A,
    0xAB59597959F220B2,
    0xD084842A8454AE15,
    0xC57272D572B7A7E4,
    0xEC3939E439D5DD72,
    0x164C4C2D4C5A6198,
    0x945E5E655ECA3BBC,
    0x9F7878FD78E785F0,
    0xE53838E038DDD870,
    0x988C8C0A8C148605,
    0x17D1D163D1C6B2BF,
    0xE4A5A5AEA5410B57,
    0xA1E2E2AFE2434DD9,
    0x4E616199612FF8C2,
    0x42B3B3F6B3F1457B,
    0x342121842115A542,
    0x089C9C4A9C94D625,
    0xEE1E1E781EF0663C,
    0x6143431143225286,
    0xB1C7C73BC776FC93,
    0x4FFCFCD7FCB32BE5,
    0x2404041004201408,
    0xE351515951B208A2,
    0x2599995E99BCC72F,
    0x226D6DA96D4FC4DA,
    0x650D0D340D68391A,
    0x79FAFACFFA8335E9,
    0x69DFDF5BDFB684A3,
    0xA97E7EE57ED79BFC,
    0x19242490243DB448,
    0xFE3B3BEC3BC5D776,
    0x9AABAB96AB313D4B,
    0xF0CECE1FCE3ED181,
    0x9911114411885522,
    0x838F8F068F0C8903,
    0x044E4E254E4A6B9C,
    0x66B7B7E6B7D15173,
    0xE0EBEB8BEB0B60CB,
    0xC13C3CF03CFDCC78,
    0xFD81813E817CBF1F,
    0x4094946A94D4FE35,
    0x1CF7F7FBF7EB0CF3,
    0x18B9B9DEB9A1676F,
    0x8B13134C13985F26,
    0x512C2CB02C7D9C58,
    0x05D3D36BD3D6B8BB,
    0x8CE7E7BBE76B5CD3,
    0x396E6EA56E57CBDC,
    0xAAC4C437C46EF395,
    0x1B03030C03180F06,
    0xDC565645568A13AC,
    0x5E44440D441A4988,
    0xA07F7FE17FDF9EFE,
    0x88A9A99EA921374F,
    0x672A2AA82A4D8254,
    0x0ABBBBD6BBB16D6B,
    0x87C1C123C146E29F,
    0xF153535153A202A6,
    0x72DCDC57DCAE8BA5,
    0x530B0B2C0B582716,
    0x019D9D4E9D9CD327,
    0x2B6C6CAD6C47C1D8,
    0xA43131C43195F562,
    0xF37474CD7487B9E8,
    0x15F6F6FFF6E309F1,
    0x4C464605460A438C,
    0xA5ACAC8AAC092645,
    0xB589891E893C970F,
    0xB414145014A04428,
    0xBAE1E1A3E15B42DF,
    0xA616165816B04E2C,
    0xF73A3AE83ACDD274,
    0x066969B9696FD0D2,
    0x4109092409482D12,
    0xD77070DD70A7ADE0,
    0x6FB6B6E2B6D95471,
    0x1ED0D067D0CEB7BD,
    0xD6EDED93ED3B7EC7,
    0xE2CCCC17CC2EDB85,
    0x68424215422A5784,
    0x2C98985A98B4C22D,
    0xEDA4A4AAA4490E55,
    0x752828A0285D8850,
    0x865C5C6D5CDA31B8,
    0x6BF8F8C7F8933FED,
    0xC28686228644A411,
]
C2 = [
    0x30D818186018C078,
    0x462623238C2305AF,
    0x91B8C6C63FC67EF9,
    0xCDFBE8E887E8136F,
    0x13CB878726874CA1,
    0x6D11B8B8DAB8A962,
    0x0209010104010805,
    0x9E0D4F4F214F426E,
    0x6C9B3636D836ADEE,
    0x51FFA6A6A2A65904,
    0xB90CD2D26FD2DEBD,
    0xF70EF5F5F3F5FB06,
    0xF2967979F979EF80,
    0xDE306F6FA16F5FCE,
    0x3F6D91917E91FCEF,
    0xA4F852525552AA07,
    0xC04760609D6027FD,
    0x6535BCBCCABC8976,
    0x2B379B9B569BACCD,
    0x018A8E8E028E048C,
    0x5BD2A3A3B6A37115,
    0x186C0C0C300C603C,
    0xF6847B7BF17BFF8A,
    0x6A803535D435B5E1,
    0x3AF51D1D741DE869,
    0xDDB3E0E0A7E05347,
    0xB321D7D77BD7F6AC,
    0x999CC2C22FC25EED,
    0x5C432E2EB82E6D96,
    0x96294B4B314B627A,
    0xE15DFEFEDFFEA321,
    0xAED5575741578216,
    0x2ABD15155415A841,
    0xEEE87777C1779FB6,
    0x6E923737DC37A5EB,
    0xD79EE5E5B3E57B56,
    0x23139F9F469F8CD9,
    0xFD23F0F0E7F0D317,
    0x94204A4A354A6A7F,
    0xA944DADA4FDA9E95,
    0xB0A258587D58FA25,
    0x8FCFC9C903C906CA,
    0x527C2929A429558D,
    0x145A0A0A280A5022,
    0x7F50B1B1FEB1E14F,
    0x5DC9A0A0BAA0691A,
    0xD6146B6BB16B7FDA,
    0x17D985852E855CAB,
    0x673CBDBDCEBD8173,
    0xBA8F5D5D695DD234,
    0x2090101040108050,
    0xF507F4F4F7F4F303,
    0x8BDDCBCB0BCB16C0,
    0x7CD33E3EF83EEDC6,
    0x0A2D050514052811,
    0xCE78676781671FE6,
    0xD597E4E4B7E47353,
    0x4E0227279C2725BB,
    0x8273414119413258,
    0x0BA78B8B168B2C9D,
    0x53F6A7A7A6A75101,
    0xFAB27D7DE97DCF94,
    0x374995956E95DCFB,
    0xAD56D8D847D88E9F,
    0xEB70FBFBCBFB8B30,
    0xC1CDEEEE9FEE2371,
    0xF8BB7C7CED7CC791,
    0xCC716666856617E3,
    0xA77BDDDD53DDA68E,
    0x2EAF17175C17B84B,
    0x8E45474701470246,
    0x211A9E9E429E84DC,
    0x89D4CACA0FCA1EC5,
    0x5A582D2DB42D7599,
    0x632EBFBFC6BF9179,
    0x0E3F07071C07381B,
    0x47ACADAD8EAD0123,
    0xB4B05A5A755AEA2F,
    0x1BEF838336836CB5,
    0x66B63333CC3385FF,
    0xC65C636391633FF2,
    0x041202020802100A,
    0x4993AAAA92AA3938,
    0xE2DE7171D971AFA8,
    0x8DC6C8C807C80ECF,
    0x32D119196419C87D,
    0x923B494939497270,
    0xAF5FD9D943D9869A,
    0xF931F2F2EFF2C31D,
    0xDBA8E3E3ABE34B48,
    0xB6B95B5B715BE22A,
    0x0DBC88881A883492,
    0x293E9A9A529AA4C8,
    0x4C0B262698262DBE,
    0x64BF3232C8328DFA,
    0x7D59B0B0FAB0E94A,
    0xCFF2E9E983E91B6A,
    0x1E770F0F3C0F7833,
    0xB733D5D573D5E6A6,
    0x1DF480803A8074BA,
    0x6127BEBEC2BE997C,
    0x87EBCDCD13CD26DE,
    0x68893434D034BDE4,
    0x903248483D487A75,
    0xE354FFFFDBFFAB24,
    0xF48D7A7AF57AF78F,
    0x3D6490907A90F4EA,
    0xBE9D5F5F615FC23E,
    0x403D202080201DA0,
    0xD00F6868BD6867D5,
    0x34CA1A1A681AD072,
    0x41B7AEAE82AE192C,
    0x757DB4B4EAB4C95E,
    0xA8CE54544D549A19,
    0x3B7F93937693ECE5,
    0x442F222288220DAA,
    0xC86364648D6407E9,
    0xFF2AF1F1E3F1DB12,
    0xE6CC7373D173BFA2,
    0x248212124812905A,
    0x807A40401D403A5D,
    0x1048080820084028,
    0x9B95C3C32BC356E8,
    0xC5DFECEC97EC337B,
    0xAB4DDBDB4BDB9690,
    0x5FC0A1A1BEA1611F,
    0x07918D8D0E8D1C83,
    0x7AC83D3DF43DF5C9,
    0x335B97976697CCF1,
    0x0000000000000000,
    0x83F9CFCF1BCF36D4,
    0x566E2B2BAC2B4587,
    0xECE17676C57697B3,
    0x19E68282328264B0,
    0xB128D6D67FD6FEA9,
    0x36C31B1B6C1BD877,
    0x7774B5B5EEB5C15B,
    0x43BEAFAF86AF1129,
    0xD41D6A6AB56A77DF,
    0xA0EA50505D50BA0D,
    0x8A5745450945124C,
    0xFB38F3F3EBF3CB18,
    0x60AD3030C0309DF0,
    0xC3C4EFEF9BEF2B74,
    0x7EDA3F3FFC3FE5C3,
    0xAAC755554955921C,
    0x59DBA2A2B2A27910,
    0xC9E9EAEA8FEA0365,
    0xCA6A656589650FEC,
    0x6903BABAD2BAB968,
    0x5E4A2F2FBC2F6593,
    0x9D8EC0C027C04EE7,
    0xA160DEDE5FDEBE81,
    0x38FC1C1C701CE06C,
    0xE746FDFDD3FDBB2E,
    0x9A1F4D4D294D5264,
    0x397692927292E4E0,
    0xEAFA7575C9758FBC,
    0x0C3606061806301E,
    0x09AE8A8A128A2498,
    0x794BB2B2F2B2F940,
    0xD185E6E6BFE66359,
    0x1C7E0E0E380E7036,
    0x3EE71F1F7C1FF863,
    0xC4556262956237F7,
    0xB53AD4D477D4EEA3,
    0x4D81A8A89AA82932,
    0x315296966296C4F4,
    0xEF62F9F9C3F99B3A,
    0x97A3C5C533C566F6,
    0x4A102525942535B1,
    0xB2AB59597959F220,
    0x15D084842A8454AE,
    0xE4C57272D572B7A7,
    0x72EC3939E439D5DD,
    0x98164C4C2D4C5A61,
    0xBC945E5E655ECA3B,
    0xF09F7878FD78E785,
    0x70E53838E038DDD8,
    0x05988C8C0A8C1486,
    0xBF17D1D163D1C6B2,
    0x57E4A5A5AEA5410B,
    0xD9A1E2E2AFE2434D,
    0xC24E616199612FF8,
    0x7B42B3B3F6B3F145,
    0x42342121842115A5,
    0x25089C9C4A9C94D6,
    0x3CEE1E1E781EF066,
    0x8661434311432252,
    0x93B1C7C73BC776FC,
    0xE54FFCFCD7FCB32B,
    0x0824040410042014,
    0xA2E351515951B208,
    0x2F2599995E99BCC7,
    0xDA226D6DA96D4FC4,
    0x1A650D0D340D6839,
    0xE979FAFACFFA8335,
    0xA369DFDF5BDFB684,
    0xFCA97E7EE57ED79B,
    0x4819242490243DB4,
    0x76FE3B3BEC3BC5D7,
    0x4B9AABAB96AB313D,
    0x81F0CECE1FCE3ED1,
    0x2299111144118855,
    0x03838F8F068F0C89,
    0x9C044E4E254E4A6B,
    0x7366B7B7E6B7D151,
    0xCBE0EBEB8BEB0B60,
    0x78C13C3CF03CFDCC,
    0x1FFD81813E817CBF,
    0x354094946A94D4FE,
    0xF31CF7F7FBF7EB0C,
    0x6F18B9B9DEB9A167,
    0x268B13134C13985F,
    0x58512C2CB02C7D9C,
    0xBB05D3D36BD3D6B8,
    0xD38CE7E7BBE76B5C,
    0xDC396E6EA56E57CB,
    0x95AAC4C437C46EF3,
    0x061B03030C03180F,
    0xACDC565645568A13,
    0x885E44440D441A49,
    0xFEA07F7FE17FDF9E,
    0x4F88A9A99EA92137,
    0x54672A2AA82A4D82,
    0x6B0ABBBBD6BBB16D,
    0x9F87C1C123C146E2,
    0xA6F153535153A202,
    0xA572DCDC57DCAE8B,
    0x16530B0B2C0B5827,
    0x27019D9D4E9D9CD3,
    0xD82B6C6CAD6C47C1,
    0x62A43131C43195F5,
    0xE8F37474CD7487B9,
    0xF115F6F6FFF6E309,
    0x8C4C464605460A43,
    0x45A5ACAC8AAC0926,
    0x0FB589891E893C97,
    0x28B414145014A044,
    0xDFBAE1E1A3E15B42,
    0x2CA616165816B04E,
    0x74F73A3AE83ACDD2,
    0xD2066969B9696FD0,
    0x124109092409482D,
    0xE0D77070DD70A7AD,
    0x716FB6B6E2B6D954,
    0xBD1ED0D067D0CEB7,
    0xC7D6EDED93ED3B7E,
    0x85E2CCCC17CC2EDB,
    0x8468424215422A57,
    0x2D2C98985A98B4C2,
    0x55EDA4A4AAA4490E,
    0x50752828A0285D88,
    0xB8865C5C6D5CDA31,
    0xED6BF8F8C7F8933F,
    0x11C28686228644A4,
]
C3 = [
    0x7830D818186018C0,
    0xAF462623238C2305,
    0xF991B8C6C63FC67E,
    0x6FCDFBE8E887E813,
    0xA113CB878726874C,
    0x626D11B8B8DAB8A9,
    0x0502090101040108,
    0x6E9E0D4F4F214F42,
    0xEE6C9B3636D836AD,
    0x0451FFA6A6A2A659,
    0xBDB90CD2D26FD2DE,
    0x06F70EF5F5F3F5FB,
    0x80F2967979F979EF,
    0xCEDE306F6FA16F5F,
    0xEF3F6D91917E91FC,
    0x07A4F852525552AA,
    0xFDC04760609D6027,
    0x766535BCBCCABC89,
    0xCD2B379B9B569BAC,
    0x8C018A8E8E028E04,
    0x155BD2A3A3B6A371,
    0x3C186C0C0C300C60,
    0x8AF6847B7BF17BFF,
    0xE16A803535D435B5,
    0x693AF51D1D741DE8,
    0x47DDB3E0E0A7E053,
    0xACB321D7D77BD7F6,
    0xED999CC2C22FC25E,
    0x965C432E2EB82E6D,
    0x7A96294B4B314B62,
    0x21E15DFEFEDFFEA3,
    0x16AED55757415782,
    0x412ABD15155415A8,
    0xB6EEE87777C1779F,
    0xEB6E923737DC37A5,
    0x56D79EE5E5B3E57B,
    0xD923139F9F469F8C,
    0x17FD23F0F0E7F0D3,
    0x7F94204A4A354A6A,
    0x95A944DADA4FDA9E,
    0x25B0A258587D58FA,
    0xCA8FCFC9C903C906,
    0x8D527C2929A42955,
    0x22145A0A0A280A50,
    0x4F7F50B1B1FEB1E1,
    0x1A5DC9A0A0BAA069,
    0xDAD6146B6BB16B7F,
    0xAB17D985852E855C,
    0x73673CBDBDCEBD81,
    0x34BA8F5D5D695DD2,
    0x5020901010401080,
    0x03F507F4F4F7F4F3,
    0xC08BDDCBCB0BCB16,
    0xC67CD33E3EF83EED,
    0x110A2D0505140528,
    0xE6CE78676781671F,
    0x53D597E4E4B7E473,
    0xBB4E0227279C2725,
    0x5882734141194132,
    0x9D0BA78B8B168B2C,
    0x0153F6A7A7A6A751,
    0x94FAB27D7DE97DCF,
    0xFB374995956E95DC,
    0x9FAD56D8D847D88E,
    0x30EB70FBFBCBFB8B,
    0x71C1CDEEEE9FEE23,
    0x91F8BB7C7CED7CC7,
    0xE3CC716666856617,
    0x8EA77BDDDD53DDA6,
    0x4B2EAF17175C17B8,
    0x468E454747014702,
    0xDC211A9E9E429E84,
    0xC589D4CACA0FCA1E,
    0x995A582D2DB42D75,
    0x79632EBFBFC6BF91,
    0x1B0E3F07071C0738,
    0x2347ACADAD8EAD01,
    0x2FB4B05A5A755AEA,
    0xB51BEF838336836C,
    0xFF66B63333CC3385,
    0xF2C65C636391633F,
    0x0A04120202080210,
    0x384993AAAA92AA39,
    0xA8E2DE7171D971AF,
    0xCF8DC6C8C807C80E,
    0x7D32D119196419C8,
    0x70923B4949394972,
    0x9AAF5FD9D943D986,
    0x1DF931F2F2EFF2C3,
    0x48DBA8E3E3ABE34B,
    0x2AB6B95B5B715BE2,
    0x920DBC88881A8834,
    0xC8293E9A9A529AA4,
    0xBE4C0B262698262D,
    0xFA64BF3232C8328D,
    0x4A7D59B0B0FAB0E9,
    0x6ACFF2E9E983E91B,
    0x331E770F0F3C0F78,
    0xA6B733D5D573D5E6,
    0xBA1DF480803A8074,
    0x7C6127BEBEC2BE99,
    0xDE87EBCDCD13CD26,
    0xE468893434D034BD,
    0x75903248483D487A,
    0x24E354FFFFDBFFAB,
    0x8FF48D7A7AF57AF7,
    0xEA3D6490907A90F4,
    0x3EBE9D5F5F615FC2,
    0xA0403D202080201D,
    0xD5D00F6868BD6867,
    0x7234CA1A1A681AD0,
    0x2C41B7AEAE82AE19,
    0x5E757DB4B4EAB4C9,
    0x19A8CE54544D549A,
    0xE53B7F93937693EC,
    0xAA442F222288220D,
    0xE9C86364648D6407,
    0x12FF2AF1F1E3F1DB,
    0xA2E6CC7373D173BF,
    0x5A24821212481290,
    0x5D807A40401D403A,
    0x2810480808200840,
    0xE89B95C3C32BC356,
    0x7BC5DFECEC97EC33,
    0x90AB4DDBDB4BDB96,
    0x1F5FC0A1A1BEA161,
    0x8307918D8D0E8D1C,
    0xC97AC83D3DF43DF5,
    0xF1335B97976697CC,
    0x0000000000000000,
    0xD483F9CFCF1BCF36,
    0x87566E2B2BAC2B45,
    0xB3ECE17676C57697,
    0xB019E68282328264,
    0xA9B128D6D67FD6FE,
    0x7736C31B1B6C1BD8,
    0x5B7774B5B5EEB5C1,
    0x2943BEAFAF86AF11,
    0xDFD41D6A6AB56A77,
    0x0DA0EA50505D50BA,
    0x4C8A574545094512,
    0x18FB38F3F3EBF3CB,
    0xF060AD3030C0309D,
    0x74C3C4EFEF9BEF2B,
    0xC37EDA3F3FFC3FE5,
    0x1CAAC75555495592,
    0x1059DBA2A2B2A279,
    0x65C9E9EAEA8FEA03,
    0xECCA6A656589650F,
    0x686903BABAD2BAB9,
    0x935E4A2F2FBC2F65,
    0xE79D8EC0C027C04E,
    0x81A160DEDE5FDEBE,
    0x6C38FC1C1C701CE0,
    0x2EE746FDFDD3FDBB,
    0x649A1F4D4D294D52,
    0xE0397692927292E4,
    0xBCEAFA7575C9758F,
    0x1E0C360606180630,
    0x9809AE8A8A128A24,
    0x40794BB2B2F2B2F9,
    0x59D185E6E6BFE663,
    0x361C7E0E0E380E70,
    0x633EE71F1F7C1FF8,
    0xF7C4556262956237,
    0xA3B53AD4D477D4EE,
    0x324D81A8A89AA829,
    0xF4315296966296C4,
    0x3AEF62F9F9C3F99B,
    0xF697A3C5C533C566,
    0xB14A102525942535,
    0x20B2AB59597959F2,
    0xAE15D084842A8454,
    0xA7E4C57272D572B7,
    0xDD72EC3939E439D5,
    0x6198164C4C2D4C5A,
    0x3BBC945E5E655ECA,
    0x85F09F7878FD78E7,
    0xD870E53838E038DD,
    0x8605988C8C0A8C14,
    0xB2BF17D1D163D1C6,
    0x0B57E4A5A5AEA541,
    0x4DD9A1E2E2AFE243,
    0xF8C24E616199612F,
    0x457B42B3B3F6B3F1,
    0xA542342121842115,
    0xD625089C9C4A9C94,
    0x663CEE1E1E781EF0,
    0x5286614343114322,
    0xFC93B1C7C73BC776,
    0x2BE54FFCFCD7FCB3,
    0x1408240404100420,
    0x08A2E351515951B2,
    0xC72F2599995E99BC,
    0xC4DA226D6DA96D4F,
    0x391A650D0D340D68,
    0x35E979FAFACFFA83,
    0x84A369DFDF5BDFB6,
    0x9BFCA97E7EE57ED7,
    0xB44819242490243D,
    0xD776FE3B3BEC3BC5,
    0x3D4B9AABAB96AB31,
    0xD181F0CECE1FCE3E,
    0x5522991111441188,
    0x8903838F8F068F0C,
    0x6B9C044E4E254E4A,
    0x517366B7B7E6B7D1,
    0x60CBE0EBEB8BEB0B,
    0xCC78C13C3CF03CFD,
    0xBF1FFD81813E817C,
    0xFE354094946A94D4,
    0x0CF31CF7F7FBF7EB,
    0x676F18B9B9DEB9A1,
    0x5F268B13134C1398,
    0x9C58512C2CB02C7D,
    0xB8BB05D3D36BD3D6,
    0x5CD38CE7E7BBE76B,
    0xCBDC396E6EA56E57,
    0xF395AAC4C437C46E,
    0x0F061B03030C0318,
    0x13ACDC565645568A,
    0x49885E44440D441A,
    0x9EFEA07F7FE17FDF,
    0x374F88A9A99EA921,
    0x8254672A2AA82A4D,
    0x6D6B0ABBBBD6BBB1,
    0xE29F87C1C123C146,
    0x02A6F153535153A2,
    0x8BA572DCDC57DCAE,
    0x2716530B0B2C0B58,
    0xD327019D9D4E9D9C,
    0xC1D82B6C6CAD6C47,
    0xF562A43131C43195,
    0xB9E8F37474CD7487,
    0x09F115F6F6FFF6E3,
    0x438C4C464605460A,
    0x2645A5ACAC8AAC09,
    0x970FB589891E893C,
    0x4428B414145014A0,
    0x42DFBAE1E1A3E15B,
    0x4E2CA616165816B0,
    0xD274F73A3AE83ACD,
    0xD0D2066969B9696F,
    0x2D12410909240948,
    0xADE0D77070DD70A7,
    0x54716FB6B6E2B6D9,
    0xB7BD1ED0D067D0CE,
    0x7EC7D6EDED93ED3B,
    0xDB85E2CCCC17CC2E,
    0x578468424215422A,
    0xC22D2C98985A98B4,
    0x0E55EDA4A4AAA449,
    0x8850752828A0285D,
    0x31B8865C5C6D5CDA,
    0x3FED6BF8F8C7F893,
    0xA411C28686228644,
]
C4 = [
    0xC07830D818186018,
    0x05AF462623238C23,
    0x7EF991B8C6C63FC6,
    0x136FCDFBE8E887E8,
    0x4CA113CB87872687,
    0xA9626D11B8B8DAB8,
    0x0805020901010401,
    0x426E9E0D4F4F214F,
    0xADEE6C9B3636D836,
    0x590451FFA6A6A2A6,
    0xDEBDB90CD2D26FD2,
    0xFB06F70EF5F5F3F5,
    0xEF80F2967979F979,
    0x5FCEDE306F6FA16F,
    0xFCEF3F6D91917E91,
    0xAA07A4F852525552,
    0x27FDC04760609D60,
    0x89766535BCBCCABC,
    0xACCD2B379B9B569B,
    0x048C018A8E8E028E,
    0x71155BD2A3A3B6A3,
    0x603C186C0C0C300C,
    0xFF8AF6847B7BF17B,
    0xB5E16A803535D435,
    0xE8693AF51D1D741D,
    0x5347DDB3E0E0A7E0,
    0xF6ACB321D7D77BD7,
    0x5EED999CC2C22FC2,
    0x6D965C432E2EB82E,
    0x627A96294B4B314B,
    0xA321E15DFEFEDFFE,
    0x8216AED557574157,
    0xA8412ABD15155415,
    0x9FB6EEE87777C177,
    0xA5EB6E923737DC37,
    0x7B56D79EE5E5B3E5,
    0x8CD923139F9F469F,
    0xD317FD23F0F0E7F0,
    0x6A7F94204A4A354A,
    0x9E95A944DADA4FDA,
    0xFA25B0A258587D58,
    0x06CA8FCFC9C903C9,
    0x558D527C2929A429,
    0x5022145A0A0A280A,
    0xE14F7F50B1B1FEB1,
    0x691A5DC9A0A0BAA0,
    0x7FDAD6146B6BB16B,
    0x5CAB17D985852E85,
    0x8173673CBDBDCEBD,
    0xD234BA8F5D5D695D,
    0x8050209010104010,
    0xF303F507F4F4F7F4,
    0x16C08BDDCBCB0BCB,
    0xEDC67CD33E3EF83E,
    0x28110A2D05051405,
    0x1FE6CE7867678167,
    0x7353D597E4E4B7E4,
    0x25BB4E0227279C27,
    0x3258827341411941,
    0x2C9D0BA78B8B168B,
    0x510153F6A7A7A6A7,
    0xCF94FAB27D7DE97D,
    0xDCFB374995956E95,
    0x8E9FAD56D8D847D8,
    0x8B30EB70FBFBCBFB,
    0x2371C1CDEEEE9FEE,
    0xC791F8BB7C7CED7C,
    0x17E3CC7166668566,
    0xA68EA77BDDDD53DD,
    0xB84B2EAF17175C17,
    0x02468E4547470147,
    0x84DC211A9E9E429E,
    0x1EC589D4CACA0FCA,
    0x75995A582D2DB42D,
    0x9179632EBFBFC6BF,
    0x381B0E3F07071C07,
    0x012347ACADAD8EAD,
    0xEA2FB4B05A5A755A,
    0x6CB51BEF83833683,
    0x85FF66B63333CC33,
    0x3FF2C65C63639163,
    0x100A041202020802,
    0x39384993AAAA92AA,
    0xAFA8E2DE7171D971,
    0x0ECF8DC6C8C807C8,
    0xC87D32D119196419,
    0x7270923B49493949,
    0x869AAF5FD9D943D9,
    0xC31DF931F2F2EFF2,
    0x4B48DBA8E3E3ABE3,
    0xE22AB6B95B5B715B,
    0x34920DBC88881A88,
    0xA4C8293E9A9A529A,
    0x2DBE4C0B26269826,
    0x8DFA64BF3232C832,
    0xE94A7D59B0B0FAB0,
    0x1B6ACFF2E9E983E9,
    0x78331E770F0F3C0F,
    0xE6A6B733D5D573D5,
    0x74BA1DF480803A80,
    0x997C6127BEBEC2BE,
    0x26DE87EBCDCD13CD,
    0xBDE468893434D034,
    0x7A75903248483D48,
    0xAB24E354FFFFDBFF,
    0xF78FF48D7A7AF57A,
    0xF4EA3D6490907A90,
    0xC23EBE9D5F5F615F,
    0x1DA0403D20208020,
    0x67D5D00F6868BD68,
    0xD07234CA1A1A681A,
    0x192C41B7AEAE82AE,
    0xC95E757DB4B4EAB4,
    0x9A19A8CE54544D54,
    0xECE53B7F93937693,
    0x0DAA442F22228822,
    0x07E9C86364648D64,
    0xDB12FF2AF1F1E3F1,
    0xBFA2E6CC7373D173,
    0x905A248212124812,
    0x3A5D807A40401D40,
    0x4028104808082008,
    0x56E89B95C3C32BC3,
    0x337BC5DFECEC97EC,
    0x9690AB4DDBDB4BDB,
    0x611F5FC0A1A1BEA1,
    0x1C8307918D8D0E8D,
    0xF5C97AC83D3DF43D,
    0xCCF1335B97976697,
    0x0000000000000000,
    0x36D483F9CFCF1BCF,
    0x4587566E2B2BAC2B,
    0x97B3ECE17676C576,
    0x64B019E682823282,
    0xFEA9B128D6D67FD6,
    0xD87736C31B1B6C1B,
    0xC15B7774B5B5EEB5,
    0x112943BEAFAF86AF,
    0x77DFD41D6A6AB56A,
    0xBA0DA0EA50505D50,
    0x124C8A5745450945,
    0xCB18FB38F3F3EBF3,
    0x9DF060AD3030C030,
    0x2B74C3C4EFEF9BEF,
    0xE5C37EDA3F3FFC3F,
    0x921CAAC755554955,
    0x791059DBA2A2B2A2,
    0x0365C9E9EAEA8FEA,
    0x0FECCA6A65658965,
    0xB9686903BABAD2BA,
    0x65935E4A2F2FBC2F,
    0x4EE79D8EC0C027C0,
    0xBE81A160DEDE5FDE,
    0xE06C38FC1C1C701C,
    0xBB2EE746FDFDD3FD,
    0x52649A1F4D4D294D,
    0xE4E0397692927292,
    0x8FBCEAFA7575C975,
    0x301E0C3606061806,
    0x249809AE8A8A128A,
    0xF940794BB2B2F2B2,
    0x6359D185E6E6BFE6,
    0x70361C7E0E0E380E,
    0xF8633EE71F1F7C1F,
    0x37F7C45562629562,
    0xEEA3B53AD4D477D4,
    0x29324D81A8A89AA8,
    0xC4F4315296966296,
    0x9B3AEF62F9F9C3F9,
    0x66F697A3C5C533C5,
    0x35B14A1025259425,
    0xF220B2AB59597959,
    0x54AE15D084842A84,
    0xB7A7E4C57272D572,
    0xD5DD72EC3939E439,
    0x5A6198164C4C2D4C,
    0xCA3BBC945E5E655E,
    0xE785F09F7878FD78,
    0xDDD870E53838E038,
    0x148605988C8C0A8C,
    0xC6B2BF17D1D163D1,
    0x410B57E4A5A5AEA5,
    0x434DD9A1E2E2AFE2,
    0x2FF8C24E61619961,
    0xF1457B42B3B3F6B3,
    0x15A5423421218421,
    0x94D625089C9C4A9C,
    0xF0663CEE1E1E781E,
    0x2252866143431143,
    0x76FC93B1C7C73BC7,
    0xB32BE54FFCFCD7FC,
    0x2014082404041004,
    0xB208A2E351515951,
    0xBCC72F2599995E99,
    0x4FC4DA226D6DA96D,
    0x68391A650D0D340D,
    0x8335E979FAFACFFA,
    0xB684A369DFDF5BDF,
    0xD79BFCA97E7EE57E,
    0x3DB4481924249024,
    0xC5D776FE3B3BEC3B,
    0x313D4B9AABAB96AB,
    0x3ED181F0CECE1FCE,
    0x8855229911114411,
    0x0C8903838F8F068F,
    0x4A6B9C044E4E254E,
    0xD1517366B7B7E6B7,
    0x0B60CBE0EBEB8BEB,
    0xFDCC78C13C3CF03C,
    0x7CBF1FFD81813E81,
    0xD4FE354094946A94,
    0xEB0CF31CF7F7FBF7,
    0xA1676F18B9B9DEB9,
    0x985F268B13134C13,
    0x7D9C58512C2CB02C,
    0xD6B8BB05D3D36BD3,
    0x6B5CD38CE7E7BBE7,
    0x57CBDC396E6EA56E,
    0x6EF395AAC4C437C4,
    0x180F061B03030C03,
    0x8A13ACDC56564556,
    0x1A49885E44440D44,
    0xDF9EFEA07F7FE17F,
    0x21374F88A9A99EA9,
    0x4D8254672A2AA82A,
    0xB16D6B0ABBBBD6BB,
    0x46E29F87C1C123C1,
    0xA202A6F153535153,
    0xAE8BA572DCDC57DC,
    0x582716530B0B2C0B,
    0x9CD327019D9D4E9D,
    0x47C1D82B6C6CAD6C,
    0x95F562A43131C431,
    0x87B9E8F37474CD74,
    0xE309F115F6F6FFF6,
    0x0A438C4C46460546,
    0x092645A5ACAC8AAC,
    0x3C970FB589891E89,
    0xA04428B414145014,
    0x5B42DFBAE1E1A3E1,
    0xB04E2CA616165816,
    0xCDD274F73A3AE83A,
    0x6FD0D2066969B969,
    0x482D124109092409,
    0xA7ADE0D77070DD70,
    0xD954716FB6B6E2B6,
    0xCEB7BD1ED0D067D0,
    0x3B7EC7D6EDED93ED,
    0x2EDB85E2CCCC17CC,
    0x2A57846842421542,
    0xB4C22D2C98985A98,
    0x490E55EDA4A4AAA4,
    0x5D8850752828A028,
    0xDA31B8865C5C6D5C,
    0x933FED6BF8F8C7F8,
    0x44A411C286862286,
]
C5 = [
    0x18C07830D8181860,
    0x2305AF462623238C,
    0xC67EF991B8C6C63F,
    0xE8136FCDFBE8E887,
    0x874CA113CB878726,
    0xB8A9626D11B8B8DA,
    0x0108050209010104,
    0x4F426E9E0D4F4F21,
    0x36ADEE6C9B3636D8,
    0xA6590451FFA6A6A2,
    0xD2DEBDB90CD2D26F,
    0xF5FB06F70EF5F5F3,
    0x79EF80F2967979F9,
    0x6F5FCEDE306F6FA1,
    0x91FCEF3F6D91917E,
    0x52AA07A4F8525255,
    0x6027FDC04760609D,
    0xBC89766535BCBCCA,
    0x9BACCD2B379B9B56,
    0x8E048C018A8E8E02,
    0xA371155BD2A3A3B6,
    0x0C603C186C0C0C30,
    0x7BFF8AF6847B7BF1,
    0x35B5E16A803535D4,
    0x1DE8693AF51D1D74,
    0xE05347DDB3E0E0A7,
    0xD7F6ACB321D7D77B,
    0xC25EED999CC2C22F,
    0x2E6D965C432E2EB8,
    0x4B627A96294B4B31,
    0xFEA321E15DFEFEDF,
    0x578216AED5575741,
    0x15A8412ABD151554,
    0x779FB6EEE87777C1,
    0x37A5EB6E923737DC,
    0xE57B56D79EE5E5B3,
    0x9F8CD923139F9F46,
    0xF0D317FD23F0F0E7,
    0x4A6A7F94204A4A35,
    0xDA9E95A944DADA4F,
    0x58FA25B0A258587D,
    0xC906CA8FCFC9C903,
    0x29558D527C2929A4,
    0x0A5022145A0A0A28,
    0xB1E14F7F50B1B1FE,
    0xA0691A5DC9A0A0BA,
    0x6B7FDAD6146B6BB1,
    0x855CAB17D985852E,
    0xBD8173673CBDBDCE,
    0x5DD234BA8F5D5D69,
    0x1080502090101040,
    0xF4F303F507F4F4F7,
    0xCB16C08BDDCBCB0B,
    0x3EEDC67CD33E3EF8,
    0x0528110A2D050514,
    0x671FE6CE78676781,
    0xE47353D597E4E4B7,
    0x2725BB4E0227279C,
    0x4132588273414119,
    0x8B2C9D0BA78B8B16,
    0xA7510153F6A7A7A6,
    0x7DCF94FAB27D7DE9,
    0x95DCFB374995956E,
    0xD88E9FAD56D8D847,
    0xFB8B30EB70FBFBCB,
    0xEE2371C1CDEEEE9F,
    0x7CC791F8BB7C7CED,
    0x6617E3CC71666685,
    0xDDA68EA77BDDDD53,
    0x17B84B2EAF17175C,
    0x4702468E45474701,
    0x9E84DC211A9E9E42,
    0xCA1EC589D4CACA0F,
    0x2D75995A582D2DB4,
    0xBF9179632EBFBFC6,
    0x07381B0E3F07071C,
    0xAD012347ACADAD8E,
    0x5AEA2FB4B05A5A75,
    0x836CB51BEF838336,
    0x3385FF66B63333CC,
    0x633FF2C65C636391,
    0x02100A0412020208,
    0xAA39384993AAAA92,
    0x71AFA8E2DE7171D9,
    0xC80ECF8DC6C8C807,
    0x19C87D32D1191964,
    0x497270923B494939,
    0xD9869AAF5FD9D943,
    0xF2C31DF931F2F2EF,
    0xE34B48DBA8E3E3AB,
    0x5BE22AB6B95B5B71,
    0x8834920DBC88881A,
    0x9AA4C8293E9A9A52,
    0x262DBE4C0B262698,
    0x328DFA64BF3232C8,
    0xB0E94A7D59B0B0FA,
    0xE91B6ACFF2E9E983,
    0x0F78331E770F0F3C,
    0xD5E6A6B733D5D573,
    0x8074BA1DF480803A,
    0xBE997C6127BEBEC2,
    0xCD26DE87EBCDCD13,
    0x34BDE468893434D0,
    0x487A75903248483D,
    0xFFAB24E354FFFFDB,
    0x7AF78FF48D7A7AF5,
    0x90F4EA3D6490907A,
    0x5FC23EBE9D5F5F61,
    0x201DA0403D202080,
    0x6867D5D00F6868BD,
    0x1AD07234CA1A1A68,
    0xAE192C41B7AEAE82,
    0xB4C95E757DB4B4EA,
    0x549A19A8CE54544D,
    0x93ECE53B7F939376,
    0x220DAA442F222288,
    0x6407E9C86364648D,
    0xF1DB12FF2AF1F1E3,
    0x73BFA2E6CC7373D1,
    0x12905A2482121248,
    0x403A5D807A40401D,
    0x0840281048080820,
    0xC356E89B95C3C32B,
    0xEC337BC5DFECEC97,
    0xDB9690AB4DDBDB4B,
    0xA1611F5FC0A1A1BE,
    0x8D1C8307918D8D0E,
    0x3DF5C97AC83D3DF4,
    0x97CCF1335B979766,
    0x0000000000000000,
    0xCF36D483F9CFCF1B,
    0x2B4587566E2B2BAC,
    0x7697B3ECE17676C5,
    0x8264B019E6828232,
    0xD6FEA9B128D6D67F,
    0x1BD87736C31B1B6C,
    0xB5C15B7774B5B5EE,
    0xAF112943BEAFAF86,
    0x6A77DFD41D6A6AB5,
    0x50BA0DA0EA50505D,
    0x45124C8A57454509,
    0xF3CB18FB38F3F3EB,
    0x309DF060AD3030C0,
    0xEF2B74C3C4EFEF9B,
    0x3FE5C37EDA3F3FFC,
    0x55921CAAC7555549,
    0xA2791059DBA2A2B2,
    0xEA0365C9E9EAEA8F,
    0x650FECCA6A656589,
    0xBAB9686903BABAD2,
    0x2F65935E4A2F2FBC,
    0xC04EE79D8EC0C027,
    0xDEBE81A160DEDE5F,
    0x1CE06C38FC1C1C70,
    0xFDBB2EE746FDFDD3,
    0x4D52649A1F4D4D29,
    0x92E4E03976929272,
    0x758FBCEAFA7575C9,
    0x06301E0C36060618,
    0x8A249809AE8A8A12,
    0xB2F940794BB2B2F2,
    0xE66359D185E6E6BF,
    0x0E70361C7E0E0E38,
    0x1FF8633EE71F1F7C,
    0x6237F7C455626295,
    0xD4EEA3B53AD4D477,
    0xA829324D81A8A89A,
    0x96C4F43152969662,
    0xF99B3AEF62F9F9C3,
    0xC566F697A3C5C533,
    0x2535B14A10252594,
    0x59F220B2AB595979,
    0x8454AE15D084842A,
    0x72B7A7E4C57272D5,
    0x39D5DD72EC3939E4,
    0x4C5A6198164C4C2D,
    0x5ECA3BBC945E5E65,
    0x78E785F09F7878FD,
    0x38DDD870E53838E0,
    0x8C148605988C8C0A,
    0xD1C6B2BF17D1D163,
    0xA5410B57E4A5A5AE,
    0xE2434DD9A1E2E2AF,
    0x612FF8C24E616199,
    0xB3F1457B42B3B3F6,
    0x2115A54234212184,
    0x9C94D625089C9C4A,
    0x1EF0663CEE1E1E78,
    0x4322528661434311,
    0xC776FC93B1C7C73B,
    0xFCB32BE54FFCFCD7,
    0x0420140824040410,
    0x51B208A2E3515159,
    0x99BCC72F2599995E,
    0x6D4FC4DA226D6DA9,
    0x0D68391A650D0D34,
    0xFA8335E979FAFACF,
    0xDFB684A369DFDF5B,
    0x7ED79BFCA97E7EE5,
    0x243DB44819242490,
    0x3BC5D776FE3B3BEC,
    0xAB313D4B9AABAB96,
    0xCE3ED181F0CECE1F,
    0x1188552299111144,
    0x8F0C8903838F8F06,
    0x4E4A6B9C044E4E25,
    0xB7D1517366B7B7E6,
    0xEB0B60CBE0EBEB8B,
    0x3CFDCC78C13C3CF0,
    0x817CBF1FFD81813E,
    0x94D4FE354094946A,
    0xF7EB0CF31CF7F7FB,
    0xB9A1676F18B9B9DE,
    0x13985F268B13134C,
    0x2C7D9C58512C2CB0,
    0xD3D6B8BB05D3D36B,
    0xE76B5CD38CE7E7BB,
    0x6E57CBDC396E6EA5,
    0xC46EF395AAC4C437,
    0x03180F061B03030C,
    0x568A13ACDC565645,
    0x441A49885E44440D,
    0x7FDF9EFEA07F7FE1,
    0xA921374F88A9A99E,
    0x2A4D8254672A2AA8,
    0xBBB16D6B0ABBBBD6,
    0xC146E29F87C1C123,
    0x53A202A6F1535351,
    0xDCAE8BA572DCDC57,
    0x0B582716530B0B2C,
    0x9D9CD327019D9D4E,
    0x6C47C1D82B6C6CAD,
    0x3195F562A43131C4,
    0x7487B9E8F37474CD,
    0xF6E309F115F6F6FF,
    0x460A438C4C464605,
    0xAC092645A5ACAC8A,
    0x893C970FB589891E,
    0x14A04428B4141450,
    0xE15B42DFBAE1E1A3,
    0x16B04E2CA6161658,
    0x3ACDD274F73A3AE8,
    0x696FD0D2066969B9,
    0x09482D1241090924,
    0x70A7ADE0D77070DD,
    0xB6D954716FB6B6E2,
    0xD0CEB7BD1ED0D067,
    0xED3B7EC7D6EDED93,
    0xCC2EDB85E2CCCC17,
    0x422A578468424215,
    0x98B4C22D2C98985A,
    0xA4490E55EDA4A4AA,
    0x285D8850752828A0,
    0x5CDA31B8865C5C6D,
    0xF8933FED6BF8F8C7,
    0x8644A411C2868622,
]
C6 = [
    0x6018C07830D81818,
    0x8C2305AF46262323,
    0x3FC67EF991B8C6C6,
    0x87E8136FCDFBE8E8,
    0x26874CA113CB8787,
    0xDAB8A9626D11B8B8,
    0x0401080502090101,
    0x214F426E9E0D4F4F,
    0xD836ADEE6C9B3636,
    0xA2A6590451FFA6A6,
    0x6FD2DEBDB90CD2D2,
    0xF3F5FB06F70EF5F5,
    0xF979EF80F2967979,
    0xA16F5FCEDE306F6F,
    0x7E91FCEF3F6D9191,
    0x5552AA07A4F85252,
    0x9D6027FDC0476060,
    0xCABC89766535BCBC,
    0x569BACCD2B379B9B,
    0x028E048C018A8E8E,
    0xB6A371155BD2A3A3,
    0x300C603C186C0C0C,
    0xF17BFF8AF6847B7B,
    0xD435B5E16A803535,
    0x741DE8693AF51D1D,
    0xA7E05347DDB3E0E0,
    0x7BD7F6ACB321D7D7,
    0x2FC25EED999CC2C2,
    0xB82E6D965C432E2E,
    0x314B627A96294B4B,
    0xDFFEA321E15DFEFE,
    0x41578216AED55757,
    0x5415A8412ABD1515,
    0xC1779FB6EEE87777,
    0xDC37A5EB6E923737,
    0xB3E57B56D79EE5E5,
    0x469F8CD923139F9F,
    0xE7F0D317FD23F0F0,
    0x354A6A7F94204A4A,
    0x4FDA9E95A944DADA,
    0x7D58FA25B0A25858,
    0x03C906CA8FCFC9C9,
    0xA429558D527C2929,
    0x280A5022145A0A0A,
    0xFEB1E14F7F50B1B1,
    0xBAA0691A5DC9A0A0,
    0xB16B7FDAD6146B6B,
    0x2E855CAB17D98585,
    0xCEBD8173673CBDBD,
    0x695DD234BA8F5D5D,
    0x4010805020901010,
    0xF7F4F303F507F4F4,
    0x0BCB16C08BDDCBCB,
    0xF83EEDC67CD33E3E,
    0x140528110A2D0505,
    0x81671FE6CE786767,
    0xB7E47353D597E4E4,
    0x9C2725BB4E022727,
    0x1941325882734141,
    0x168B2C9D0BA78B8B,
    0xA6A7510153F6A7A7,
    0xE97DCF94FAB27D7D,
    0x6E95DCFB37499595,
    0x47D88E9FAD56D8D8,
    0xCBFB8B30EB70FBFB,
    0x9FEE2371C1CDEEEE,
    0xED7CC791F8BB7C7C,
    0x856617E3CC716666,
    0x53DDA68EA77BDDDD,
    0x5C17B84B2EAF1717,
    0x014702468E454747,
    0x429E84DC211A9E9E,
    0x0FCA1EC589D4CACA,
    0xB42D75995A582D2D,
    0xC6BF9179632EBFBF,
    0x1C07381B0E3F0707,
    0x8EAD012347ACADAD,
    0x755AEA2FB4B05A5A,
    0x36836CB51BEF8383,
    0xCC3385FF66B63333,
    0x91633FF2C65C6363,
    0x0802100A04120202,
    0x92AA39384993AAAA,
    0xD971AFA8E2DE7171,
    0x07C80ECF8DC6C8C8,
    0x6419C87D32D11919,
    0x39497270923B4949,
    0x43D9869AAF5FD9D9,
    0xEFF2C31DF931F2F2,
    0xABE34B48DBA8E3E3,
    0x715BE22AB6B95B5B,
    0x1A8834920DBC8888,
    0x529AA4C8293E9A9A,
    0x98262DBE4C0B2626,
    0xC8328DFA64BF3232,
    0xFAB0E94A7D59B0B0,
    0x83E91B6ACFF2E9E9,
    0x3C0F78331E770F0F,
    0x73D5E6A6B733D5D5,
    0x3A8074BA1DF48080,
    0xC2BE997C6127BEBE,
    0x13CD26DE87EBCDCD,
    0xD034BDE468893434,
    0x3D487A7590324848,
    0xDBFFAB24E354FFFF,
    0xF57AF78FF48D7A7A,
    0x7A90F4EA3D649090,
    0x615FC23EBE9D5F5F,
    0x80201DA0403D2020,
    0xBD6867D5D00F6868,
    0x681AD07234CA1A1A,
    0x82AE192C41B7AEAE,
    0xEAB4C95E757DB4B4,
    0x4D549A19A8CE5454,
    0x7693ECE53B7F9393,
    0x88220DAA442F2222,
    0x8D6407E9C8636464,
    0xE3F1DB12FF2AF1F1,
    0xD173BFA2E6CC7373,
    0x4812905A24821212,
    0x1D403A5D807A4040,
    0x2008402810480808,
    0x2BC356E89B95C3C3,
    0x97EC337BC5DFECEC,
    0x4BDB9690AB4DDBDB,
    0xBEA1611F5FC0A1A1,
    0x0E8D1C8307918D8D,
    0xF43DF5C97AC83D3D,
    0x6697CCF1335B9797,
    0x0000000000000000,
    0x1BCF36D483F9CFCF,
    0xAC2B4587566E2B2B,
    0xC57697B3ECE17676,
    0x328264B019E68282,
    0x7FD6FEA9B128D6D6,
    0x6C1BD87736C31B1B,
    0xEEB5C15B7774B5B5,
    0x86AF112943BEAFAF,
    0xB56A77DFD41D6A6A,
    0x5D50BA0DA0EA5050,
    0x0945124C8A574545,
    0xEBF3CB18FB38F3F3,
    0xC0309DF060AD3030,
    0x9BEF2B74C3C4EFEF,
    0xFC3FE5C37EDA3F3F,
    0x4955921CAAC75555,
    0xB2A2791059DBA2A2,
    0x8FEA0365C9E9EAEA,
    0x89650FECCA6A6565,
    0xD2BAB9686903BABA,
    0xBC2F65935E4A2F2F,
    0x27C04EE79D8EC0C0,
    0x5FDEBE81A160DEDE,
    0x701CE06C38FC1C1C,
    0xD3FDBB2EE746FDFD,
    0x294D52649A1F4D4D,
    0x7292E4E039769292,
    0xC9758FBCEAFA7575,
    0x1806301E0C360606,
    0x128A249809AE8A8A,
    0xF2B2F940794BB2B2,
    0xBFE66359D185E6E6,
    0x380E70361C7E0E0E,
    0x7C1FF8633EE71F1F,
    0x956237F7C4556262,
    0x77D4EEA3B53AD4D4,
    0x9AA829324D81A8A8,
    0x6296C4F431529696,
    0xC3F99B3AEF62F9F9,
    0x33C566F697A3C5C5,
    0x942535B14A102525,
    0x7959F220B2AB5959,
    0x2A8454AE15D08484,
    0xD572B7A7E4C57272,
    0xE439D5DD72EC3939,
    0x2D4C5A6198164C4C,
    0x655ECA3BBC945E5E,
    0xFD78E785F09F7878,
    0xE038DDD870E53838,
    0x0A8C148605988C8C,
    0x63D1C6B2BF17D1D1,
    0xAEA5410B57E4A5A5,
    0xAFE2434DD9A1E2E2,
    0x99612FF8C24E6161,
    0xF6B3F1457B42B3B3,
    0x842115A542342121,
    0x4A9C94D625089C9C,
    0x781EF0663CEE1E1E,
    0x1143225286614343,
    0x3BC776FC93B1C7C7,
    0xD7FCB32BE54FFCFC,
    0x1004201408240404,
    0x5951B208A2E35151,
    0x5E99BCC72F259999,
    0xA96D4FC4DA226D6D,
    0x340D68391A650D0D,
    0xCFFA8335E979FAFA,
    0x5BDFB684A369DFDF,
    0xE57ED79BFCA97E7E,
    0x90243DB448192424,
    0xEC3BC5D776FE3B3B,
    0x96AB313D4B9AABAB,
    0x1FCE3ED181F0CECE,
    0x4411885522991111,
    0x068F0C8903838F8F,
    0x254E4A6B9C044E4E,
    0xE6B7D1517366B7B7,
    0x8BEB0B60CBE0EBEB,
    0xF03CFDCC78C13C3C,
    0x3E817CBF1FFD8181,
    0x6A94D4FE35409494,
    0xFBF7EB0CF31CF7F7,
    0xDEB9A1676F18B9B9,
    0x4C13985F268B1313,
    0xB02C7D9C58512C2C,
    0x6BD3D6B8BB05D3D3,
    0xBBE76B5CD38CE7E7,
    0xA56E57CBDC396E6E,
    0x37C46EF395AAC4C4,
    0x0C03180F061B0303,
    0x45568A13ACDC5656,
    0x0D441A49885E4444,
    0xE17FDF9EFEA07F7F,
    0x9EA921374F88A9A9,
    0xA82A4D8254672A2A,
    0xD6BBB16D6B0ABBBB,
    0x23C146E29F87C1C1,
    0x5153A202A6F15353,
    0x57DCAE8BA572DCDC,
    0x2C0B582716530B0B,
    0x4E9D9CD327019D9D,
    0xAD6C47C1D82B6C6C,
    0xC43195F562A43131,
    0xCD7487B9E8F37474,
    0xFFF6E309F115F6F6,
    0x05460A438C4C4646,
    0x8AAC092645A5ACAC,
    0x1E893C970FB58989,
    0x5014A04428B41414,
    0xA3E15B42DFBAE1E1,
    0x5816B04E2CA61616,
    0xE83ACDD274F73A3A,
    0xB9696FD0D2066969,
    0x2409482D12410909,
    0xDD70A7ADE0D77070,
    0xE2B6D954716FB6B6,
    0x67D0CEB7BD1ED0D0,
    0x93ED3B7EC7D6EDED,
    0x17CC2EDB85E2CCCC,
    0x15422A5784684242,
    0x5A98B4C22D2C9898,
    0xAAA4490E55EDA4A4,
    0xA0285D8850752828,
    0x6D5CDA31B8865C5C,
    0xC7F8933FED6BF8F8,
    0x228644A411C28686,
]
C7 = [
    0x186018C07830D818,
    0x238C2305AF462623,
    0xC63FC67EF991B8C6,
    0xE887E8136FCDFBE8,
    0x8726874CA113CB87,
    0xB8DAB8A9626D11B8,
    0x0104010805020901,
    0x4F214F426E9E0D4F,
    0x36D836ADEE6C9B36,
    0xA6A2A6590451FFA6,
    0xD26FD2DEBDB90CD2,
    0xF5F3F5FB06F70EF5,
    0x79F979EF80F29679,
    0x6FA16F5FCEDE306F,
    0x917E91FCEF3F6D91,
    0x525552AA07A4F852,
    0x609D6027FDC04760,
    0xBCCABC89766535BC,
    0x9B569BACCD2B379B,
    0x8E028E048C018A8E,
    0xA3B6A371155BD2A3,
    0x0C300C603C186C0C,
    0x7BF17BFF8AF6847B,
    0x35D435B5E16A8035,
    0x1D741DE8693AF51D,
    0xE0A7E05347DDB3E0,
    0xD77BD7F6ACB321D7,
    0xC22FC25EED999CC2,
    0x2EB82E6D965C432E,
    0x4B314B627A96294B,
    0xFEDFFEA321E15DFE,
    0x5741578216AED557,
    0x155415A8412ABD15,
    0x77C1779FB6EEE877,
    0x37DC37A5EB6E9237,
    0xE5B3E57B56D79EE5,
    0x9F469F8CD923139F,
    0xF0E7F0D317FD23F0,
    0x4A354A6A7F94204A,
    0xDA4FDA9E95A944DA,
    0x587D58FA25B0A258,
    0xC903C906CA8FCFC9,
    0x29A429558D527C29,
    0x0A280A5022145A0A,
    0xB1FEB1E14F7F50B1,
    0xA0BAA0691A5DC9A0,
    0x6BB16B7FDAD6146B,
    0x852E855CAB17D985,
    0xBDCEBD8173673CBD,
    0x5D695DD234BA8F5D,
    0x1040108050209010,
    0xF4F7F4F303F507F4,
    0xCB0BCB16C08BDDCB,
    0x3EF83EEDC67CD33E,
    0x05140528110A2D05,
    0x6781671FE6CE7867,
    0xE4B7E47353D597E4,
    0x279C2725BB4E0227,
    0x4119413258827341,
    0x8B168B2C9D0BA78B,
    0xA7A6A7510153F6A7,
    0x7DE97DCF94FAB27D,
    0x956E95DCFB374995,
    0xD847D88E9FAD56D8,
    0xFBCBFB8B30EB70FB,
    0xEE9FEE2371C1CDEE,
    0x7CED7CC791F8BB7C,
    0x66856617E3CC7166,
    0xDD53DDA68EA77BDD,
    0x175C17B84B2EAF17,
    0x47014702468E4547,
    0x9E429E84DC211A9E,
    0xCA0FCA1EC589D4CA,
    0x2DB42D75995A582D,
    0xBFC6BF9179632EBF,
    0x071C07381B0E3F07,
    0xAD8EAD012347ACAD,
    0x5A755AEA2FB4B05A,
    0x8336836CB51BEF83,
    0x33CC3385FF66B633,
    0x6391633FF2C65C63,
    0x020802100A041202,
    0xAA92AA39384993AA,
    0x71D971AFA8E2DE71,
    0xC807C80ECF8DC6C8,
    0x196419C87D32D119,
    0x4939497270923B49,
    0xD943D9869AAF5FD9,
    0xF2EFF2C31DF931F2,
    0xE3ABE34B48DBA8E3,
    0x5B715BE22AB6B95B,
    0x881A8834920DBC88,
    0x9A529AA4C8293E9A,
    0x2698262DBE4C0B26,
    0x32C8328DFA64BF32,
    0xB0FAB0E94A7D59B0,
    0xE983E91B6ACFF2E9,
    0x0F3C0F78331E770F,
    0xD573D5E6A6B733D5,
    0x803A8074BA1DF480,
    0xBEC2BE997C6127BE,
    0xCD13CD26DE87EBCD,
    0x34D034BDE4688934,
    0x483D487A75903248,
    0xFFDBFFAB24E354FF,
    0x7AF57AF78FF48D7A,
    0x907A90F4EA3D6490,
    0x5F615FC23EBE9D5F,
    0x2080201DA0403D20,
    0x68BD6867D5D00F68,
    0x1A681AD07234CA1A,
    0xAE82AE192C41B7AE,
    0xB4EAB4C95E757DB4,
    0x544D549A19A8CE54,
    0x937693ECE53B7F93,
    0x2288220DAA442F22,
    0x648D6407E9C86364,
    0xF1E3F1DB12FF2AF1,
    0x73D173BFA2E6CC73,
    0x124812905A248212,
    0x401D403A5D807A40,
    0x0820084028104808,
    0xC32BC356E89B95C3,
    0xEC97EC337BC5DFEC,
    0xDB4BDB9690AB4DDB,
    0xA1BEA1611F5FC0A1,
    0x8D0E8D1C8307918D,
    0x3DF43DF5C97AC83D,
    0x976697CCF1335B97,
    0x0000000000000000,
    0xCF1BCF36D483F9CF,
    0x2BAC2B4587566E2B,
    0x76C57697B3ECE176,
    0x82328264B019E682,
    0xD67FD6FEA9B128D6,
    0x1B6C1BD87736C31B,
    0xB5EEB5C15B7774B5,
    0xAF86AF112943BEAF,
    0x6AB56A77DFD41D6A,
    0x505D50BA0DA0EA50,
    0x450945124C8A5745,
    0xF3EBF3CB18FB38F3,
    0x30C0309DF060AD30,
    0xEF9BEF2B74C3C4EF,
    0x3FFC3FE5C37EDA3F,
    0x554955921CAAC755,
    0xA2B2A2791059DBA2,
    0xEA8FEA0365C9E9EA,
    0x6589650FECCA6A65,
    0xBAD2BAB9686903BA,
    0x2FBC2F65935E4A2F,
    0xC027C04EE79D8EC0,
    0xDE5FDEBE81A160DE,
    0x1C701CE06C38FC1C,
    0xFDD3FDBB2EE746FD,
    0x4D294D52649A1F4D,
    0x927292E4E0397692,
    0x75C9758FBCEAFA75,
    0x061806301E0C3606,
    0x8A128A249809AE8A,
    0xB2F2B2F940794BB2,
    0xE6BFE66359D185E6,
    0x0E380E70361C7E0E,
    0x1F7C1FF8633EE71F,
    0x62956237F7C45562,
    0xD477D4EEA3B53AD4,
    0xA89AA829324D81A8,
    0x966296C4F4315296,
    0xF9C3F99B3AEF62F9,
    0xC533C566F697A3C5,
    0x25942535B14A1025,
    0x597959F220B2AB59,
    0x842A8454AE15D084,
    0x72D572B7A7E4C572,
    0x39E439D5DD72EC39,
    0x4C2D4C5A6198164C,
    0x5E655ECA3BBC945E,
    0x78FD78E785F09F78,
    0x38E038DDD870E538,
    0x8C0A8C148605988C,
    0xD163D1C6B2BF17D1,
    0xA5AEA5410B57E4A5,
    0xE2AFE2434DD9A1E2,
    0x6199612FF8C24E61,
    0xB3F6B3F1457B42B3,
    0x21842115A5423421,
    0x9C4A9C94D625089C,
    0x1E781EF0663CEE1E,
    0x4311432252866143,
    0xC73BC776FC93B1C7,
    0xFCD7FCB32BE54FFC,
    0x0410042014082404,
    0x515951B208A2E351,
    0x995E99BCC72F2599,
    0x6DA96D4FC4DA226D,
    0x0D340D68391A650D,
    0xFACFFA8335E979FA,
    0xDF5BDFB684A369DF,
    0x7EE57ED79BFCA97E,
    0x2490243DB4481924,
    0x3BEC3BC5D776FE3B,
    0xAB96AB313D4B9AAB,
    0xCE1FCE3ED181F0CE,
    0x1144118855229911,
    0x8F068F0C8903838F,
    0x4E254E4A6B9C044E,
    0xB7E6B7D1517366B7,
    0xEB8BEB0B60CBE0EB,
    0x3CF03CFDCC78C13C,
    0x813E817CBF1FFD81,
    0x946A94D4FE354094,
    0xF7FBF7EB0CF31CF7,
    0xB9DEB9A1676F18B9,
    0x134C13985F268B13,
    0x2CB02C7D9C58512C,
    0xD36BD3D6B8BB05D3,
    0xE7BBE76B5CD38CE7,
    0x6EA56E57CBDC396E,
    0xC437C46EF395AAC4,
    0x030C03180F061B03,
    0x5645568A13ACDC56,
    0x440D441A49885E44,
    0x7FE17FDF9EFEA07F,
    0xA99EA921374F88A9,
    0x2AA82A4D8254672A,
    0xBBD6BBB16D6B0ABB,
    0xC123C146E29F87C1,
    0x535153A202A6F153,
    0xDC57DCAE8BA572DC,
    0x0B2C0B582716530B,
    0x9D4E9D9CD327019D,
    0x6CAD6C47C1D82B6C,
    0x31C43195F562A431,
    0x74CD7487B9E8F374,
    0xF6FFF6E309F115F6,
    0x4605460A438C4C46,
    0xAC8AAC092645A5AC,
    0x891E893C970FB589,
    0x145014A04428B414,
    0xE1A3E15B42DFBAE1,
    0x165816B04E2CA616,
    0x3AE83ACDD274F73A,
    0x69B9696FD0D20669,
    0x092409482D124109,
    0x70DD70A7ADE0D770,
    0xB6E2B6D954716FB6,
    0xD067D0CEB7BD1ED0,
    0xED93ED3B7EC7D6ED,
    0xCC17CC2EDB85E2CC,
    0x4215422A57846842,
    0x985A98B4C22D2C98,
    0xA4AAA4490E55EDA4,
    0x28A0285D88507528,
    0x5C6D5CDA31B8865C,
    0xF8C7F8933FED6BF8,
    0x86228644A411C286,
]

rc = [
    0x0000000000000000,
    0x1823C6E887B8014F,
    0x36A6D2F5796F9152,
    0x60BC9B8EA30C7B35,
    0x1DE0D7C22E4BFE57,
    0x157737E59FF04ADA,
    0x58C9290AB1A06B85,
    0xBD5D10F4CB3E0567,
    0xE427418BA77D95D8,
    0xFBEE7C66DD17479E,
    0xCA2DBF07AD5A8333,
]

DIGESTBYTES = 64


class WhirlpoolStruct:
    def __init__(self):
        self.bitLength = [0] * 32
        self.buffer = [0] * 64
        self.bufferBits = 0
        self.bufferPos = 0
        self.hash = [0] * 8


def WhirlpoolInit(ctx):
    ctx = WhirlpoolStruct()


def WhirlpoolAdd(source, sourceBits, ctx):
    if not isinstance(source, bytes):
        raise TypeError(f"Expected {bytes}, got {type(source)}")
    if sourceBits == 0:
        return

    carry = 0
    value = sourceBits
    i = 31
    while i >= 0 and (carry != 0 or value != 0):
        carry += ctx.bitLength[i] + ((value % 0x100000000) & 0xFF)
        ctx.bitLength[i] = carry % 0x100
        carry >>= 8
        value >>= 8
        i -= 1

    bufferBits = ctx.bufferBits
    bufferPos = ctx.bufferPos
    sourcePos = 0
    sourceGap = (8 - (sourceBits & 7)) & 7
    bufferRem = ctx.bufferBits & 7
    buffr = ctx.buffer

    while sourceBits > 8:
        b = ((source[sourcePos] << sourceGap) & 0xFF) | (
            (source[sourcePos + 1] & 0xFF) >> (8 - sourceGap)
        )
        buffr[bufferPos] |= (b >> bufferRem) % 0x100
        bufferPos += 1
        bufferBits += 8 - bufferRem
        if bufferBits == 512:
            processBuffer(ctx)
            bufferBits = 0
            bufferPos = 0

        buffr[bufferPos] = b << (8 - bufferRem)
        bufferBits += bufferRem

        sourceBits -= 8
        sourcePos += 1

    b = (source[sourcePos] << sourceGap) & 0xFF
    buffr[bufferPos] |= b >> bufferRem
    if bufferRem + sourceBits < 8:
        bufferBits += sourceBits
    else:
        bufferPos += 1
        bufferBits += 8 - bufferRem
        sourceBits -= 8 - bufferRem
        if bufferBits == 512:
            processBuffer(ctx)
            bufferBits = 0
            bufferPos = 0
        buffr[bufferPos] = b << (8 - bufferRem)
        bufferBits += sourceBits
    ctx.bufferBits = bufferBits
    ctx.bufferPos = bufferPos


def WhirlpoolFinalize(ctx):
    bufferPos = ctx.bufferPos
    ctx.buffer[bufferPos] |= 0x80 >> (ctx.bufferBits & 7)
    bufferPos += 1
    if bufferPos > 32:
        if bufferPos < 64:
            for i in range(64 - bufferPos):
                ctx.buffer[bufferPos + i] = 0
        processBuffer(ctx)
        bufferPos = 0
    if bufferPos < 32:
        for i in range(32 - bufferPos):
            ctx.buffer[bufferPos + i] = 0
    bufferPos = 32
    for i in range(32):
        ctx.buffer[32 + i] = ctx.bitLength[i]
    processBuffer(ctx)
    digest = ""
    for i in range(8):
        digest += chr((ctx.hash[i] >> 56) % 0x100)
        digest += chr((ctx.hash[i] >> 48) % 0x100)
        digest += chr((ctx.hash[i] >> 40) % 0x100)
        digest += chr((ctx.hash[i] >> 32) % 0x100)
        digest += chr((ctx.hash[i] >> 24) % 0x100)
        digest += chr((ctx.hash[i] >> 16) % 0x100)
        digest += chr((ctx.hash[i] >> 8) % 0x100)
        digest += chr((ctx.hash[i]) % 0x100)
    ctx.bufferPos = bufferPos
    return digest


def CDo(buf, a0, a1, a2, a3, a4, a5, a6, a7):
    return (
        C0[((buf[a0] >> 56) % 0x100000000) & 0xFF]
        ^ C1[((buf[a1] >> 48) % 0x100000000) & 0xFF]
        ^ C2[((buf[a2] >> 40) % 0x100000000) & 0xFF]
        ^ C3[((buf[a3] >> 32) % 0x100000000) & 0xFF]
        ^ C4[((buf[a4] >> 24) % 0x100000000) & 0xFF]
        ^ C5[((buf[a5] >> 16) % 0x100000000) & 0xFF]
        ^ C6[((buf[a6] >> 8) % 0x100000000) & 0xFF]
        ^ C7[((buf[a7] >> 0) % 0x100000000) & 0xFF]
    )


def processBuffer(ctx):
    i, r = 0, 0
    K = [0] * 8
    block = [0] * 8
    state = [0] * 8
    L = [0] * 8
    buffr = ctx.buffer

    buf_cnt = 0
    for i in range(8):
        block[i] = (
            ((buffr[buf_cnt + 0] & 0xFF) << 56)
            ^ ((buffr[buf_cnt + 1] & 0xFF) << 48)
            ^ ((buffr[buf_cnt + 2] & 0xFF) << 40)
            ^ ((buffr[buf_cnt + 3] & 0xFF) << 32)
            ^ ((buffr[buf_cnt + 4] & 0xFF) << 24)
            ^ ((buffr[buf_cnt + 5] & 0xFF) << 16)
            ^ ((buffr[buf_cnt + 6] & 0xFF) << 8)
            ^ ((buffr[buf_cnt + 7] & 0xFF) << 0)
        )
        buf_cnt += 8
    for i in range(8):
        K[i] = ctx.hash[i]
        state[i] = block[i] ^ K[i]

    for r in range(1, R + 1):
        L[0] = CDo(K, 0, 7, 6, 5, 4, 3, 2, 1) ^ rc[r]
        L[1] = CDo(K, 1, 0, 7, 6, 5, 4, 3, 2)
        L[2] = CDo(K, 2, 1, 0, 7, 6, 5, 4, 3)
        L[3] = CDo(K, 3, 2, 1, 0, 7, 6, 5, 4)
        L[4] = CDo(K, 4, 3, 2, 1, 0, 7, 6, 5)
        L[5] = CDo(K, 5, 4, 3, 2, 1, 0, 7, 6)
        L[6] = CDo(K, 6, 5, 4, 3, 2, 1, 0, 7)
        L[7] = CDo(K, 7, 6, 5, 4, 3, 2, 1, 0)
        for i in range(8):
            K[i] = L[i]
        L[0] = CDo(state, 0, 7, 6, 5, 4, 3, 2, 1) ^ K[0]
        L[1] = CDo(state, 1, 0, 7, 6, 5, 4, 3, 2) ^ K[1]
        L[2] = CDo(state, 2, 1, 0, 7, 6, 5, 4, 3) ^ K[2]
        L[3] = CDo(state, 3, 2, 1, 0, 7, 6, 5, 4) ^ K[3]
        L[4] = CDo(state, 4, 3, 2, 1, 0, 7, 6, 5) ^ K[4]
        L[5] = CDo(state, 5, 4, 3, 2, 1, 0, 7, 6) ^ K[5]
        L[6] = CDo(state, 6, 5, 4, 3, 2, 1, 0, 7) ^ K[6]
        L[7] = CDo(state, 7, 6, 5, 4, 3, 2, 1, 0) ^ K[7]
        for i in range(8):
            state[i] = L[i]
    # apply the Miyaguchi-Preneel compression function
    for i in range(8):
        ctx.hash[i] ^= state[i] ^ block[i]
